﻿
(function ($) {
    var _credentialsKey = "Ao75sYhQSfLgssT0QkO9n22xt0lgxzntrZ1xpCwLOC-kGhI584OYED3viFXLIWgC"; //LS team key
    //var _credentialsKey = "AuhA6S9HYETsgrMhBMN-kmxOgdkTV6Fit-1VJZQ3nZWMtu59oWptjiwKqJyo0Nn0"; //my key http://www.bingmapsportal.com/
    // load the directions module only once per session
    Microsoft.Maps.loadModule('Microsoft.Maps.Directions');
    // load the search module only once per session
    Microsoft.Maps.loadModule('Microsoft.Maps.Search');

    $.widget("msls.lightswitchBingMapsControl", {
        options: {
            mapType: Microsoft.Maps.MapTypeId.road,
            zoom: 16,
            showDashboard: true
        },

        _create: function () {
        },

        _init: function () {
            this.createMap();
        },

        destroy: function () {
            this._destroyBingMapsControl();
        },

        createMap: function () {
            this.htmlMapElement = this.element[0];

            // create empty map
            this.map = new Microsoft.Maps.Map(this.htmlMapElement,
            {
                credentials: _credentialsKey,
                mapTypeId: this.options.mapType,
                zoom: this.options.zoom,
                showDashboard: this.options.showDashboard

            });
            this.map.addComponent('searchManager', new Microsoft.Maps.Search.SearchManager(this.map));
        },

        _addPinAsync: function (street, city, country, callback) {

            var widgetInstance = this;

            // construct a request to the REST geocode service using the widget's
            // optional parameters
            var geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations/" +
                                 street + "," + city + "," + country +
                                 "?key=" + _credentialsKey;

            // make the ajax request to the Bing Maps geocode REST service
            $.ajax({
                url: geocodeRequest,
                dataType: 'jsonp',
                async: true,
                jsonp: 'jsonp',
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert(textStatus + " " + errorThrown);
                },
                success: function (result) {
                    var coordinates = null;

                    if (result && result.resourceSets && (result.resourceSets.length > 0) &&
                        result.resourceSets[0].resources && (result.resourceSets[0].resources.length > 0)) {

                        // create a location based on the geocoded coordinates
                        coordinates = result.resourceSets[0].resources[0].point.coordinates;

                        widgetInstance._createPinFromCoordinates2(coordinates, callback);
                    }
                }
            });
        },

        resetMap: function () {
            this.map.entities.clear();
            //this.map.setView({ zoom: this.options.zoom, center: location })
        },

        getPositionByAddress: function (place) {
            this.map.Find(null,    // what
                          place.Address, // where
                          null,    // VEFindType (always VEFindType.Businesses)
                          null,    // VEShapeLayer (base by default)
                          null,    // start index for results (0 by default)
                          null,    // max number of results (default is 10)
                          null,    // show results? (default is true)
                          null,    // create pushpin for what results? (ignored since what is null)
                          null,    // use default disambiguation? (default is true)
                          null,    // set best map view? (default is true)
                          function (shapeLayer, findResults, places, moreResults, errorMsg) {
                              // if there are no results, display any error message and return
                              if (places == null) {
                                  alert((errorMsg == null) ? "There were no results" : errorMsg);
                                  return;
                              }
                              var bestPlace = places[0];
                              // Add pushpin to the *best* place
                              var centerPosition = bestPlace.LatLong;
                              place.Latitude = centerPosition.latitude;
                              place.Longitude = centerPosition.longitude;
                          });  // call back function
        },

        _GeocodeCallback: function (shapeLayer, findResults, places, moreResults, errorMsg)
        {
            // if there are no results, display any error message and return
            if(places == null)
            {
                alert( (errorMsg == null) ? "There were no results" : errorMsg );
                return;
            }

            var bestPlace = places[0];
   
            // Add pushpin to the *best* place
            var centerPosition = bestPlace.LatLong;
            screen.Place.Latitude = centerPosition.latitude;
            screen.Place.Longitude = centerPosition.longitude;
            //widgetInstance._setMarkerPosition(centerPosition, screen);

            //var newShape = new VEShape(VEShapeType.Pushpin, location);
   
            //var desc = "Latitude: " + location.Latitude + "<br>Longitude:" + location.Longitude;
            //newShape.SetDescription(desc);
            //newShape.SetTitle(bestPlace.Name);
            //this.map.AddShape(newShape);
        },

        getCurrentPosition: function (place) {
            var widgetInstance = this;
            var isDraggable = (place.Draggable == null || place.Draggable == true);
            var map = this.map;
            if (map != null && map.entities != null)
                map.entities.clear();
            var searchManager = map.getComponent('searchManager');
            var zoomoption = this.options.zoom;
            if (place.Latitude != null && place.Longitude != null) {
                var startLocation = new Microsoft.Maps.Location(place.Latitude, place.Longitude);
                map.setView({ zoom: this.options.zoom, center: startLocation });
                var pin1 = new Microsoft.Maps.Pushpin(startLocation, { text: '1', draggable: isDraggable });
                map.entities.push(pin1);
                /*
                var pin1InfoBox = new Microsoft.Maps.Infobox(
                    startLocation,
                    {
                        title: place.Name,
                        description: place.Address,
                        pushpin: pin1,
                        offset: new Microsoft.Maps.Point(10, 10)
                    }
                );
                map.entities.push(pin1InfoBox);
                */
                if (isDraggable)
                {
                    Microsoft.Maps.Events.addHandler(pin1, 'dragend', function () {
                        var pinLocation = pin1.getLocation();
                        place.Latitude = pinLocation.latitude;
                        place.Longitude = pinLocation.longitude;
                        searchManager.reverseGeocode({
                            location: pinLocation,
                            callback: function (result) {
                                if (result) {
                                    place.Address = result.name;
                                    /*if (pin1InfoBox != null)
                                        pin1InfoBox.description = result.name;*/
                                }
                                else {
                                    place.Address = 'no Address found, try panning map';
                                }
                            }
                        });
                    });
                }
            }
        },

        getStaticPositions: function (places, callback) {
            var map = this.map;
            if (map != null && map.entities != null)
                map.entities.clear();
            /*for (var i = map.entities.getLength() - 1; i >= 0; i--) {
                var pushpin = map.entities.get(i);
                if (pushpin instanceof Microsoft.Maps.Pushpin) {
                    map.entities.removeAt(i);
                };
            }*/

            //var searchManager = map.getComponent('searchManager');
            var zoomoption = this.options.zoom;
            $.each(places, function (index, place) {
                if (place.Latitude != null && place.Longitude != null) {
                    var placeLocation = new Microsoft.Maps.Location(place.Latitude, place.Longitude);
                    var placeId = place.Id;
                    var infoboxOptions = {
                        title: place.Name + ' (' + place.Id + ')', description: place.Address,
                        offset:new Microsoft.Maps.Point(0,15)
                        /*, actions: [
                            {
                                label: 'Use',
                                eventHandler: function (placeId, screenPlace) {
                                    myapp.activeDataWorkspace.MMC_Content.PlacesFiltered(null, null, null, placeId)
                                        .execute().then(function (results) {
                                            results.forEach(function (foundPlace) {
                                                screenPlace = foundPlace;
                                            });
                                        });
                                }
                            },
                            {
                                label: 'Show',
                                eventHandler: function (placeId) {
                                    alert(placeId);
                                }
                            }
                        ]*/
                    };
                    var placeInfobox = new Microsoft.Maps.Infobox(placeLocation, infoboxOptions);
                    map.entities.push(placeInfobox);

                    //map.setView({ zoom: zoomoption, center: placeLocation });
                    var pin1 = new Microsoft.Maps.Pushpin(placeLocation, { text: place.Id, draggable: false });
                    Microsoft.Maps.Events.addHandler(pin1, 'click', function () {
                        if (callback && typeof (callback) === "function") {
                            callback(place.Id);
                        }
                    });
                    map.entities.push(pin1);
                }
            });
        },

        /*testTraffic: function (screen) {
            var map = this.map;
            this.map.setView({ zoom: 10, center: new Microsoft.Maps.Location(-34.928585333329150, 138.595880510589600) })
            Microsoft.Maps.loadModule('Microsoft.Maps.Traffic', {
                callback: function () {
                    trafficLayer = new Microsoft.Maps.Traffic.TrafficLayer(map);
                    // show the traffic Layer 
                    trafficLayer.show();
                }
            });
        },*/

        getCenter: function (callback) {
            if (callback && typeof (callback) === "function") {
                callback(this.map.getCenter());
            }
        },
        setCenter: function (place) {
            var startLocation = new Microsoft.Maps.Location(place.Latitude, place.Longitude);
            this.map.setView({ zoom: this.options.zoom, center: startLocation });
        },

        createMovementRoute: function (fromPlace, toPlace, drivingMode, trafficMode) {
            if (!this.directionsManager) {
                this.directionsManager = new Microsoft.Maps.Directions.DirectionsManager(this.map);
            }

            var directionsManager = this.directionsManager;
            directionsManager.resetDirections();
            // Set Route Mode to driving 
            directionsManager.setRequestOptions({
                routeMode: ((drivingMode) && (drivingMode === true) ? Microsoft.Maps.Directions.RouteMode.walking : Microsoft.Maps.Directions.RouteMode.driving), //driving ,transit, walking 
            });
            //var widgetInstance = this;
            //if (!fromPlace.Latitude || !fromPlace.Longitude)
            //    widgetInstance.getCurrentPosition(fromPlace);
            //if (!toPlace.Latitude || !toPlace.Longitude)
            //    widgetInstance.getCurrentPosition(toPlace);
            var fromPoint = new Microsoft.Maps.Directions.Waypoint({ address: fromPlace.Address, location: new Microsoft.Maps.Location(fromPlace.Latitude, fromPlace.Longitude) });
            var toPoint = new Microsoft.Maps.Directions.Waypoint({ address: toPlace.Address, location: new Microsoft.Maps.Location(toPlace.Latitude, toPlace.Longitude) });
            
            this.map.setView({ zoom: this.options.zoom, center: fromPoint.getLocation() });

            directionsManager.addWaypoint(fromPoint);
            directionsManager.addWaypoint(toPoint);
            // Set the element in which the itinerary will be rendered
            var panel = document.getElementById("directionsItinerary");
            panel.innerHTML = "";
            directionsManager.setRenderOptions({ itineraryContainer: panel, distanceUnit: Microsoft.Maps.Directions.DistanceUnit.kilometers, routeOptimization: Microsoft.Maps.Directions.RouteOptimization.shortestDistance }); //screen.directionsItinerary
            directionsManager.calculateDirections();

            if ((trafficMode != null) && (trafficMode === true) && (!this.trafficLayer)) {
                var map = this.map;
                var trafficLayer = this.trafficLayer;
                Microsoft.Maps.loadModule('Microsoft.Maps.Traffic', {
                    callback: function () {
                        trafficLayer = new Microsoft.Maps.Traffic.TrafficLayer(map);
                        if (trafficLayer != null) {
                            trafficLayer.show();
                        }
                    }
                });
            }
            else if ((trafficMode != null) && (trafficMode === false)) {
                if (this.trafficLayer != null) {
                    this.trafficLayer.hide();
                }
            }
        },

        _handleError: function (error) {
            alert("An error occurred.  " + error.message);
        },

        _destroyBingMapsControl: function () {
            if (this.map != null) {
                this.map.dispose();
                this.map = null;
            }
        }
    });
}(jQuery));
